const db = uniCloud.database()
const $ = db.command
const groupCollection = db.collection('Group') // 假设集合名为 groups (与schema对应)
const userCollection = db.collection('linli-user') // 用户集合 (关联ownId)
const now = Date.now()
const linliUtils = require('linliUtils')

module.exports = {
    _before: async function() {
        // 前置校验：获取当前登录用户ID (根据实际登录机制调整)
        // this.userId = this.getClientInfo().userId // 需配合权限中间件获取真实用户ID
        // if (!this.userId) {
        //   throw new Error('请先登录')
        // }
    },

    /**
     * 创建群聊
     * @param {string} userId 创建者Id
     * @param {Object} params 创建参数
     * @param {string} params.groupName 群名
     * @param {string} params.signature 群介绍
     * @param {Object} params.location 位置中心点 ({latitude, longitude})
     * @param {number} params.radius 范围半径 (米)
     * @param {boolean} params.needApproval 是否需要群主同意入群 (默认true)
     * @param {boolean} params.visibleInRange 是否仅位置范围内可见 (默认true)
     * @param {Array} [params.groupPicPath] 群头像和群相片，群头像为0索引
     * @returns {Object} 群信息
     */
    async createGroup(userId, params) {
        const {
            groupName,
            signature,
            location,
            groupUser, // [{userId: this.userId, role: 'owner', joinTime: now}],
            radius,
            needApproval = true,
            visibleInRange = true,
            groupPicPath
        } = params

        // 参数校验
        if (!groupName || !location || !radius) {
            throw new Error('群名、位置和范围为必填项')
        }
        
        // 注意：此处 forEach 中的 async 函数不会等待，请使用 for...of 或 Promise.all
        var newGroupUser = []
        for (const item of groupUser) {
            if (item.userId) {
                newGroupUser.push({
                    ...item,
                    joinTime: now,
                    role: userId === item.userId ? 'owner' : 'member'
                })
            } else {
                const res = await userCollection.where({
                    userTel: item.userTel
                }).field({
                    userId: true
                }).get()
                if (res.data.length > 0) {
                    const newId = res.data[0].userId
                    newGroupUser.push({
                        ...item,
                        userId: newId,
                        joinTime: now,
                        role: 'member',
                        joinType: 'invited'
                    })
                } else {
                    // 不建议在创建群聊时自动创建用户，这可能导致垃圾数据
                    // 建议先检查用户是否存在，不存在则提示邀请失败
                    throw new Error(`用户 ${item.userTel} 不存在，无法邀请入群`)
                }
            }
        }

        const newParam = {
            ...params,
            groupUser: [...newGroupUser]
        }

        // 生成群ID (可自定义规则)
        const groupId = `group_${Date.now()}_${Math.floor(Math.random() * 1000)}`

        // 获取群主信息
        const userRes = await userCollection.where({
            userId: userId
        }).field({
            userId: 1,
            nicName: 1,
            nicPic: 1
        }).get()
        if (userRes.data.length === 0) {
            throw new Error('用户信息不存在')
        }

        // 插入群数据
        const groupData = {
            groupId,
            ...newParam,
            ownId: userId,
            ownInfo: userRes.data[0], // 群主信息
            registTime: now,
            status: 'active', // 群状态：active-正常，dissolved-已解散
            pendingUsers: [] // 待审批的入群申请
        }

        await groupCollection.add(groupData)
        
        // 通知所有成员加入群聊（更新用户的 groups 字段）
        const membersId = groupData.groupUser.map(item => item.userId)
        // 使用 Promise.all 等待所有更新完成
        await Promise.all(membersId.map(id => 
            userCollection.where({ userId: id }).update({
                groups: $.push({ groupId: groupId, isAgree: false })
            })
        ))

        return {
            code: 0,
            message: '群聊创建成功',
            data: {
                groupId,
                ...groupData
            }
        }
    },

    /**
     * 解散群聊 (仅群主可操作)
     * @param {string} userId 用户Id
     * @param {string} groupId 群ID
     * @returns {Object} 操作结果
     */
    async dissolveGroup(userId, { groupId }) {
        if (!groupId) {
            throw new Error('群ID不能为空')
        }

        // 校验群存在且当前用户是群主
        const group = await groupCollection.where({
            groupId,
            status: 'active'
        }).get()
        if (group.data.length === 0) {
            throw new Error('群聊不存在或已解散')
        }
        if (group.data[0].ownId !== userId) {
            throw new Error('无权限解散群聊 (仅群主可操作)')
        }

        // 更新群状态为已解散
        await groupCollection.where({ groupId }).update({
            status: 'dissolved',
            dissolveTime: Date.now()
        })
        
        // 可选：通知所有成员群已解散（更新其 groups 字段）
        const membersId = group.data[0].groupUser.map(item => item.userId);
        await Promise.all(membersId.map(id => 
            userCollection.where({ userId: id }).update({
                groups: $.pull({ groupId: groupId })
            })
        ));

        return { code: 0, message: '群聊已解散' }
    },

   /**
    * 批量邀请用户入群 (群主或管理员可操作，无需审批)
    * @param {string} userId 操作人ID (邀请者)
    * @param {Object} params 参数
    * @param {string} params.groupId 群ID
    * @param {Array<string>} params.clientIds 被邀请用户ID数组
    * @returns {Object} 操作结果汇总
    */
   async inviteUser(userId, { groupId, clientIds }) {
       // 1. 前置参数与状态校验 (只做一次)
       if (!groupId) {
           throw new Error('群ID不能为空');
       }
       if (!Array.isArray(clientIds) || clientIds.length === 0) {
           throw new Error('被邀请用户ID列表必须是一个非空数组');
       }
   
       // 校验群状态
       const groupRes = await groupCollection.where({
           groupId,
           status: 'active'
       }).get();
       if (groupRes.data.length === 0) {
          return {
			  code:-1,
			  message:'群已解散'
		  }
       }
       const groupData = groupRes.data[0];
   
       // 校验邀请者权限
       // const inviter = groupData.groupUser.find(u => u.userId === userId);
       // if (!inviter || !['owner', 'admin'].includes(inviter.role)) {
       //     throw new Error('无权限邀请用户 (仅群主或管理员可操作)');
       // }
   
       // 2. 批量处理邀请
       const results = {
           success: [],
           fail: []
       };
   
       // 使用 Promise.all 并行处理所有邀请，以提高效率
       await Promise.all(clientIds.map(async (clientId) => {
           try {
               // 对每个用户执行邀请逻辑
               // 校验被邀请用户是否已在群内
               const isInGroup = groupData.groupUser.some(u => u.userId === clientId);
               if (isInGroup) {
                   results.fail.push({ clientId, reason: '该用户已在群内' });
                   return; // 跳过后续步骤
               }
   
               // 获取被邀请用户信息
               const userRes = await userCollection.where({ userId: clientId }).field({
                   userId: 1, nicName: 1, nicPic: 1
               }).get();
               if (userRes.data.length === 0) {
                   results.fail.push({ clientId, reason: '被邀请用户不存在' });
                   return; // 跳过后续步骤
               }
   
               // 添加用户到群成员列表
               await groupCollection.where({ groupId }).update({
                   groupUser: $.push({
                       userId: clientId,
                       role: 'member',
                       joinTime: Date.now(),
                       joinType: 'invited'
                   })
               });
               
               // 更新被邀请用户的 groups 字段
               await userCollection.where({ userId: clientId }).update({
                   groups: $.push({ groupId: groupId, isAgree: true })
               });
   
               // 如果所有步骤都成功
               results.success.push({ clientId, message: '邀请成功' });
   
           } catch (error) {
               // 捕获单个用户邀请过程中可能发生的其他未知错误
               console.error(`邀请用户 ${clientId} 失败:`, error);
               results.fail.push({ clientId, reason: `邀请失败: ${error.message}` });
           }
       }));
   
       // 3. 返回汇总结果
       return {
           code: 0,
           message: `批量邀请处理完成。成功: ${results.success.length} 人, 失败: ${results.fail.length} 人。`,
           data: results
       };
   },
    /**
     * 修改群名称 (仅群主可操作)
     * @param {string} userId 操作人ID
     * @param {Object} params 参数
     * @param {string} params.groupId 群ID
     * @param {string} params.newGroupName 新的群名称
     * @returns {Object} 操作结果
     */
    async editGroupName(userId, { groupId, newGroupName }) {
        if (!groupId || !newGroupName) {
            throw new Error('群ID和新群名称不能为空')
        }
        if (newGroupName.length > 30) { // 限制群名长度
            throw new Error('群名称过长，请控制在30个字符以内')
        }

        // 1. 校验群存在且为活跃状态
        const groupRes = await groupCollection.where({
            groupId,
            status: 'active'
        }).get();
        if (groupRes.data.length === 0) {
            throw new Error('群聊不存在或已解散');
        }
        const groupData = groupRes.data[0];

        // 2. 校验操作人是否为群主
        if (groupData.ownId !== userId) {
            throw new Error('无权限修改群名称 (仅群主可操作)');
        }
        
        // 3. 更新群名称
        await groupCollection.where({ groupId }).update({
            groupName: newGroupName
        });

        return { code: 0, message: '群名称修改成功' };
    },

    /**
     * 申请入群 (用户主动申请)
     * @param {string} userId 申请人ID
     * @param {Object} params 参数
     * @param {string} params.groupId 群ID
     * @param {Object} [params.userLocation] 用户当前位置 ({latitude, longitude})
     * @returns {Object} 操作结果
     */
    async applyJoin(userId, { groupId, userLocation }) {
        if (!groupId) {
            return { code: -1, message: '群ID不能为空' }
        }

        const groupRes = await groupCollection.where({
            groupId,
            status: 'active'
        }).get()
        if (groupRes.data.length === 0) {
            return { code: -1, message: '群不存在或已解散' }
        }
        const groupData = groupRes.data[0]

        // 检查是否已在群内
        if (groupData.groupUser.some(u => u.userId === userId)) {
            return { code: -2, message: '您已在群内' }
        }

        // 检查是否已在待审批列表
        if (groupData.pendingUsers && groupData.pendingUsers.some(u => u.userId === userId)) {
            return { code: -3, message: '您的入群申请已提交，请等待群主同意' }
        }

        // 范围校验
        if (groupData.visibleInRange && userLocation) {
            const distance = this.calcDistance(
                userLocation.latitude, userLocation.longitude,
                groupData.location.latitude, groupData.location.longitude
            )
            if (distance > groupData.radius) {
                return { code: -4, message: '您不在群的可见范围内，无法申请入群' }
            }
        }

        // 获取申请人信息
        const userRes = await userCollection.where({ userId }).field({
            userId: 1, nicName: 1, nicPic: 1
        }).get()
        if (userRes.data.length === 0) {
            throw new Error('申请人信息未找到')
        }

        // 根据群设置决定是直接加入还是需要审批
        const needApproval = groupData.needApproval !== false;
        if (needApproval) {
            // 需要审批
            await groupCollection.where({ groupId }).update({
                pendingUsers: $.push({
                    userId: userId,
                    userInfo: userRes.data[0],
                    applyTime: Date.now()
                })
            })
            return { code: 0, message: '入群申请已提交，请等待群主同意' }
        } else {
            // 无需审批，直接加入
            await groupCollection.where({ groupId }).update({
                groupUser: $.push({
                    userId: userId,
                    role: 'member',
                    joinTime: Date.now(),
                    joinType: 'applied'
                })
            })
            await userCollection.where({ userId }).update({
                groups: $.push({ groupId: groupId, isAgree: true })
            })
            return { code: 1, message: '入群成功' }
        }
    },

    /**
     * 同意入群申请 (仅群主可操作)
     * @param {string} userId 操作人ID (群主)
     * @param {Object} params 参数
     * @param {string} params.groupId 群ID
     * @param {string} params.clientId 申请人ID
     * @returns {Object} 操作结果
     */
    async approveApply(userId, { groupId, clientId }) {
        if (!groupId || !clientId) {
            throw new Error('群ID和用户ID不能为空')
        }

        const groupRes = await groupCollection.where({
            groupId,
            status: 'active'
        }).get()
        if (groupRes.data.length === 0) {
            throw new Error('群聊不存在或已解散')
        }
        const groupData = groupRes.data[0]

        if (groupData.ownId !== userId) {
            throw new Error('无权限审批 (仅群主可操作)')
        }

        // 检查申请是否存在
        const pendingIndex = groupData.pendingUsers.findIndex(u => u.userId === clientId)
        if (pendingIndex === -1) {
            throw new Error('该用户无入群申请')
        }
        
        // 从待审批列表移除，并添加到成员列表
        const approvedUser = groupData.pendingUsers[pendingIndex];
        await groupCollection.where({ groupId }).update({
            pendingUsers: $.pull({ userId: clientId }),
            groupUser: $.push({
                userId: clientId,
                role: 'member',
                joinTime: Date.now(),
                joinType: 'applied'
            })
        })
        
        // 更新用户的 groups 字段
        await userCollection.where({ userId: clientId }).update({
            groups: $.push({ groupId: groupId, isAgree: true })
        })

        return { code: 0, message: '已同意入群申请' }
    },
/**
 * 踢出群聊 (仅群主可操作)
 * @param {string} userId 操作人ID (群主)
 * @param {Object} params 参数
 * @param {string} params.groupId 群ID
 * @param {string} params.clientId 被踢用户ID
 * @returns {Object} 操作结果
 */
async kickUser(userId, { groupId, clientId }) {
    try {
        if (!groupId || !clientId) {
            // throw new Error('群ID和用户ID不能为空');
            return { code: -1, message: '群ID和用户ID不能为空' };
        }
        if (userId === clientId) {
            // throw new Error('不能将自己踢出群聊');
            return { code: -1, message: '不能将自己踢出群聊' };
        }

        const groupRes = await groupCollection.where({
            groupId,
            status: 'active'
        }).get();
        if (groupRes.data.length === 0) {
            // throw new Error('群聊不存在或已解散');
            return { code: -1, message: '群聊不存在或已解散' };
        }
        const groupData = groupRes.data[0];

        if (groupData.ownId !== userId) {
            // throw new Error('无权限踢人 (仅群主可操作)');
            return { code: -1, message: '无权限踢人 (仅群主可操作)' };
        }

        const isInGroup = groupData.groupUser.some(u => u.userId === clientId);
        if (!isInGroup) {
            // throw new Error('该用户不在群内');
            return { code: -1, message: '该用户不在群内' };
        }

        // 从群成员列表移除 - 修正 $.pull 的语法
        await groupCollection.where({ groupId }).update({
            groupUser: $.pull('groupUser', { userId: clientId })
        });
        
        // 从用户的 groups 字段中移除该群
        await userCollection.where({ userId: clientId }).update({
            groups: $.pull('groups', { groupId: groupId })
        });

        return { code: 0, message: '已将用户踢出群聊' };

    } catch (error) {
        // 捕获系统级异常，如数据库连接失败等
        console.error("踢人操作发生系统错误:", error);
        return { 
            code: -999, 
            message: '服务器内部错误，请稍后再试',
            error: error.message // 可在开发环境返回详细错误，生产环境移除
        };
    }
},
/**
 * 退出群聊 (群成员主动操作)
 * @param {string} userId 操作人ID (即要退出群聊的用户自己)
 * @param {Object} params 参数
 * @param {string} params.groupId 群ID
 * @returns {Object} 操作结果
 */
async quitGroup(userId, { groupId }) {
    try {
        // 1. 参数校验
        if (!groupId || !userId) {
            return { code: -1, message: '群ID和用户ID不能为空' };
        }

        // 2. 校验群状态
        const groupRes = await groupCollection.where({
            groupId,
            status: 'active'
        }).get();
        if (groupRes.data.length === 0) {
            return { code: -1, message: '群聊不存在或已解散' };
        }
        const groupData = groupRes.data[0];

        // 3. 校验用户是否在群内
        const isInGroup = groupData.groupUser.some(u => u.userId === userId);
        if (!isInGroup) {
            return { code: -1, message: '你不在该群聊中' };
        }
        
        // 4. 执行退出操作
        // 4.1 从群的成员列表中移除该用户
        await groupCollection.where({ groupId }).update({
            groupUser: $.pull('groupUser', { userId: userId })
        });
        
        // 4.2 从用户的群列表中移除该群
        await userCollection.where({ userId: userId }).update({
            groups: $.pull('groups', { groupId: groupId })
        });

        // 5. 返回成功结果
        return { code: 0, message: '已成功退出群聊' };

    } catch (error) {
        // 捕获系统级异常
        console.error("退出群聊操作发生系统错误:", error);
        return { 
            code: -999, 
            message: '服务器内部错误，请稍后再试'
        };
    }
},

    /**
     * 分享群卡片
     * @param {string} userId 用户ID
     * @param {Object} params 参数
     * @param {string} params.groupId 群ID
     * @returns {Object} 群卡片信息
     */
    async shareGroupCard(userId, { groupId }) {
        if (!groupId) {
            throw new Error('群ID不能为空')
        }

        const group = await groupCollection.where({
            groupId,
            status: 'active'
        }).field({
            groupId: 1,
            groupName: 1,
            signature: 1,
            groupPicPath: 1,
            ownInfo: { nicName: 1, nicPic: 1 },
            memberCount: $.size('$groupUser')
        }).get()

        if (group.data.length === 0) {
            throw new Error('群聊不存在或已解散')
        }

        return {
            code: 0,
            data: {
                ...group.data[0],
                shareTime: Date.now()
            }
        }
    },

    /**
     * 获取用户加入的所有群
     * @param {string} userId 用户ID
     * @returns {Object} 群列表
     */
    async getGroup(userId) {
        try {
            const userRes = await userCollection.where({ userId }).field({ groups: true }).get()
            if (!userRes.data.length || !userRes.data[0].groups || userRes.data[0].groups.length === 0) {
                return { code: -1, msg: '该用户未加入任何群聊' }
            }

            const groupIds = userRes.data[0].groups.map(item => item.groupId)
            const groupRes = await groupCollection.where({
                groupId: $.in(groupIds),
                status: 'active' // 只返回活跃的群
            }).get()

            return { code: 0, data: groupRes.data }
        } catch (e) {
            console.error(e)
            return { code: -1, msg: '获取群列表失败', error: e.message }
        }
    },

    /**
     * 根据群ID获取群详情
     * @param {string} userId 用户ID (用于权限校验，例如查看非公开群)
     * @param {Object} params 参数
     * @param {string} params.groupId 群ID
     * @returns {Object} 群详情
     */
    async getGroupBygroupId(userId, { groupId }) {
        try {
            const res = await groupCollection.where({ groupId }).get()
            if (res.data.length) {
                // 可以在这里添加权限校验逻辑，例如：
                // if (res.data[0].visibleInRange) { ... }
                return { code: true, data: res.data[0] }
            } else {
                return { code: false, errMsg: '未查到群' }
            }
        } catch (e) {
            console.error(e)
            return { code: false, errMsg: '查找出错', error: e.message }
        }
    },

    /**
     * 辅助方法：计算两点地理距离 (米)
     * @param {number} lat1 纬度1
     * @param {number} lon1 经度1
     * @param {number} lat2 纬度2
     * @param {number} lon2 经度2
     * @returns {number} 距离 (米)
     */
    calcDistance(lat1, lon1, lat2, lon2) {
        const R = 6371e3; // 地球半径 (米)
        const φ1 = lat1 * Math.PI / 180;
        const φ2 = lat2 * Math.PI / 180;
        const Δφ = (lat2 - lat1) * Math.PI / 180;
        const Δλ = (lon2 - lon1) * Math.PI / 180;
        const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
            Math.cos(φ1) * Math.cos(φ2) *
            Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
        const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return R * c;
    }
}